﻿package frEngine.primitives.lightingline
{
    import __AS3__.vec.*;
    import baseEngine.basic.*;
    import baseEngine.core.*;
    import baseEngine.system.*;
    import flash.geom.*;
    import frEngine.core.*;
    import frEngine.render.*;
    import frEngine.render.layer.*;
    import frEngine.shader.*;
    import frEngine.shader.filters.*;

    public class FrFlashLine extends Mesh3D
    {
        public var _forceTexLoop:Boolean;
        public var _width:Number;
        public var lineStep:Number;
        public var _textureLength:Number;
        public var _amplitude0:Number;
        public var _frequency0:Number;
        public var _waveWide0:Number;
        public var _amplitude1:Number;
        public var _frequency1:Number;
        public var _waveWide1:Number;
        public var _timeFactor:Number;
        public var _uvSpeed:Number;
        public var _attenuation:Number;
        public var _lineType:int;
        protected var _lines:Vector.<NoiseLine>;
        private var _dirty:Boolean;
        private var _time:Number;
        private var _initTime:Number;
        private var _lastTickTime:Number;
        protected var _escapeTime:Number = 0;
        private var _surf:FrSurface3D;
        public static const LT_Direct:int = 1;
        public static const LT_Random:int = 2;
        public static const LT_PerlinNoise:int = 3;
        public static const ST_Begin:int = 1;
        public static const ST_End:int = 2;
        public static const ST_Other:int = 3;
        private static var _indexVector:Vector.<uint> = new Vector.<uint>;
        private static var _noise:FrNoise = new FrNoise(-1);
        private static const VertexCount:uint = 4;
        private static var vertex0:VertexColorCoord1 = new VertexColorCoord1();
        private static var vertex1:VertexColorCoord1 = new VertexColorCoord1();
        private static var vertex2:VertexColorCoord1 = new VertexColorCoord1();
        private static var vertex3:VertexColorCoord1 = new VertexColorCoord1();
        private static var vertexList:Vector.<VertexColorCoord1> = FrFlashLine.Vector.<VertexColorCoord1>([vertex0, vertex1, vertex2, vertex3]);

        public function FrFlashLine(param1:String, param2:Boolean, param3:RenderList)
        {
            super(param1, param2, param3);
            this.render = FlashLightingRender.instance;
            this._surf = new FrSurface3D("noiseLine");
            this._surf.addVertexData(FilterName_ID.POSITION_ID, 3, false, null);
            this._surf.addVertexData(FilterName_ID.UV_ID, 2, false, null);
            this._forceTexLoop = false;
            this._time = 0;
            this._attenuation = 0;
            this._lineType = LT_PerlinNoise;
            this._dirty = true;
            this._initTime = 0;
            this._lastTickTime = this._initTime;
            this._forceTexLoop = false;
            this._width = 5;
            this._textureLength = 25;
            this.lineStep = 0.6;
            this._amplitude0 = 2.2;
            this._frequency0 = 3;
            this._waveWide0 = 0;
            this._amplitude1 = 0.8;
            this._frequency1 = 50;
            this._waveWide1 = 0;
            this._timeFactor = 1;
            this._uvSpeed = 1;
            this.init();
            return;
        }// end function

        public function disposeLines() : void
        {
            this._lines = null;
            return;
        }// end function

        private function init(param1 = null) : void
        {
            if (!param1)
            {
                param1 = "lighting.png";
            }
            this.setMateiralBlendMode(EBlendType.BLEND_LIGHT);
            this.material.materialParams.depthWrite = false;
            this.material.materialParams.twoSided = true;
            this.setLayer(Layer3DManager.AlphaLayer0);
            this.setMaterial(param1, Texture3D.MIP_NONE, "flashLine");
            return;
        }// end function

        public function SetLines(param1:Vector.<NoiseLine>) : void
        {
            this._lines = param1;
            this.setPosition(0, 0, 0);
            this._dirty = true;
            return;
        }// end function

        override public function update(param1:int = 0) : void
        {
            super.update(param1);
            this._time = this.timerContorler.totalframe / Global3D.animateSpeedFrame;
            this._escapeTime = Math.abs(this._time - this._lastTickTime);
            if (this._escapeTime > 0)
            {
                this._dirty = true;
            }
            this._lastTickTime = this._time;
            return;
        }// end function

        override public function draw(param1:Boolean = true, param2:ShaderBase = null) : void
        {
            if (this._dirty)
            {
            }
            super.draw(param1, param2);
            return;
        }// end function

        override public function dispose(param1:Boolean = true) : void
        {
            super.dispose(param1);
            this._surf.download();
            return;
        }// end function

        private function updateMesh() : void
        {
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:NoiseLine = null;
            var _loc_6:Vector3D = null;
            var _loc_7:Vector3D = null;
            var _loc_8:Number = NaN;
            var _loc_9:Vector3D = null;
            var _loc_10:Number = NaN;
            var _loc_11:Number = NaN;
            var _loc_12:Number = NaN;
            var _loc_13:Number = NaN;
            var _loc_14:Vector3D = null;
            var _loc_15:Vector3D = null;
            var _loc_16:Vector3D = null;
            var _loc_17:Number = NaN;
            var _loc_18:Vector3D = null;
            var _loc_19:FrSurface3D = null;
            var _loc_20:FrVertexBuffer3D = null;
            var _loc_21:Vector.<Number> = null;
            var _loc_22:int = 0;
            var _loc_23:int = 0;
            var _loc_24:Number = NaN;
            var _loc_25:Number = NaN;
            var _loc_26:Vector3D = null;
            var _loc_27:Vector3D = null;
            var _loc_28:Number = NaN;
            var _loc_29:Number = NaN;
            var _loc_30:Number = NaN;
            var _loc_1:* = this._lines.length;
            this.surfaces.length = _loc_1;
            var _loc_2:uint = 0;
            while (_loc_2 < _loc_1)
            {
                
                _loc_3 = this._width * 0.5;
                _loc_4 = this._textureLength != 0 ? (1 / this._textureLength) : (1);
                _loc_5 = this._lines[_loc_2];
                _loc_6 = _loc_5.lineBegin;
                _loc_7 = _loc_5.lineEnd;
                _loc_8 = _loc_5.beginOffset;
                _loc_9 = _loc_7.subtract(_loc_6);
                _loc_10 = _loc_9.length;
                _loc_9.normalize();
                _loc_11 = _loc_10 != 0 ? (1 / _loc_10) : (1);
                _loc_12 = this.lineStep;
                _loc_13 = _loc_10 <= _loc_12 * 2 ? (2) : (Math.ceil(_loc_10 / _loc_12));
                _loc_12 = _loc_10 / _loc_13;
                _loc_14 = _loc_9.crossProduct(Global3D.cameraForward);
                _loc_14.normalize();
                _loc_15 = _loc_6.clone();
                _loc_16 = _loc_7.clone();
                _loc_17 = 0;
                _loc_18 = new Vector3D(_loc_14.x * _loc_3, _loc_14.y * _loc_3, _loc_14.z * _loc_3);
                _loc_19 = this.getSurface(_loc_2);
                if (!_loc_19)
                {
                    _loc_19 = this._surf;
                    this.setSurface(_loc_2, _loc_19);
                }
                _loc_20 = _loc_19.getVertexBufferByNameId(FilterName_ID.POSITION_ID);
                _loc_21 = _loc_20.vertexVector;
                _loc_21.length = 0;
                _indexVector = _loc_19.indexVector;
                if (!_indexVector)
                {
                    _indexVector = new Vector.<uint>;
                    _loc_19.indexVector = _indexVector;
                }
                _indexVector.length = 0;
                _loc_22 = _loc_13 - 1;
                _loc_23 = 0;
                while (_loc_23 < _loc_22)
                {
                    
                    _loc_26 = new Vector3D(0, 0, 0);
                    switch(this._lineType)
                    {
                        case LT_Direct:
                        {
                            break;
                        }
                        case LT_Random:
                        {
                            _loc_26.setTo(this._amplitude0, this._amplitude0, this._amplitude0);
                            _loc_26.x = _loc_26.x * Math.random();
                            _loc_26.y = _loc_26.y * Math.random();
                            _loc_26.z = _loc_26.z * Math.random();
                            break;
                        }
                        case LT_PerlinNoise:
                        {
                            _loc_28 = this._time * this._timeFactor + _loc_17 * _loc_11 + _loc_8;
                            _loc_29 = _noise.generateNoise2D(_loc_28 * this._frequency0, _loc_17 * _loc_11 * this._waveWide0) * this._amplitude0;
                            _loc_29 = _loc_29 + _noise.generateNoise2D(_loc_28 * this._frequency1 + 1000, _loc_17 * _loc_11 * this._waveWide1) * this._amplitude1;
                            _loc_30 = Math.min(_loc_17, _loc_10 - _loc_17);
                            if (_loc_30 < this._attenuation)
                            {
                                _loc_29 = _loc_29 * Math.pow(_loc_30 / this._attenuation, 4);
                            }
                            _loc_26.setTo(_loc_14.x * _loc_29, _loc_14.y * _loc_29, _loc_14.z * _loc_29);
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                    if (this._lineType == LT_Direct)
                    {
                        break;
                    }
                    _loc_27 = new Vector3D(_loc_9.x * (_loc_17 + _loc_12), _loc_9.y * (_loc_17 + _loc_12), _loc_9.z * (_loc_17 + _loc_12));
                    _loc_16 = _loc_6.add(_loc_27);
                    _loc_16.incrementBy(_loc_26);
                    this.addOneStep(_loc_21, _indexVector, _loc_17 == 0 ? (_loc_6) : (_loc_15), _loc_16, _loc_18, _loc_17 * _loc_4 - this._time * this._uvSpeed, (_loc_17 + _loc_12) * _loc_4 - this._time * this._uvSpeed, _loc_17 == 0 ? (ST_Begin) : (ST_Other));
                    _loc_17 = _loc_17 + _loc_12;
                    _loc_15 = _loc_16;
                    _loc_23++;
                }
                _loc_24 = _loc_17 * _loc_4;
                _loc_25 = _loc_10 * _loc_4;
                if (this._forceTexLoop)
                {
                    _loc_25 = Math.ceil(_loc_25);
                }
                if (this._lineType == LT_Direct)
                {
                    this.addOneStep(_loc_21, _indexVector, _loc_15, _loc_7, _loc_18, _loc_24 - this._time * this._uvSpeed, _loc_24 - this._time * this._uvSpeed + 1, ST_End);
                }
                else
                {
                    this.addOneStep(_loc_21, _indexVector, _loc_15, _loc_7, _loc_18, _loc_24 - this._time * this._uvSpeed, _loc_25 - this._time * this._uvSpeed, ST_End);
                }
                _loc_20.toUpdate();
                _loc_19.indexBufferFr.toUpdate();
                _loc_19.impUpload = true;
                _loc_2 = _loc_2 + 1;
            }
            this._dirty = false;
            return;
        }// end function

        private function addOneStep(param1:Vector.<Number>, param2:Vector.<uint>, param3:Vector3D, param4:Vector3D, param5:Vector3D, param6:Number, param7:Number, param8:int) : void
        {
            var _loc_12:VertexColorCoord1 = null;
            var _loc_13:int = 0;
            switch(param8)
            {
                case ST_Begin:
                {
                    vertex0.position = param3.add(param5);
                    vertex1.position = param4.add(param5);
                    vertex2.position = param4.subtract(param5);
                    vertex3.position = param3.subtract(param5);
                    vertex0.u = param6;
                    vertex1.u = param7;
                    vertex2.u = param7;
                    vertex3.u = param6;
                    vertex0.v = 0;
                    vertex1.v = 0;
                    vertex2.v = 1;
                    vertex3.v = 1;
                    break;
                }
                case ST_End:
                {
                    vertex0.position = param3.add(param5);
                    vertex1.position = param4.add(param5);
                    vertex2.position = param4.subtract(param5);
                    vertex3.position = param3.subtract(param5);
                    vertex0.u = param6;
                    vertex1.u = param7;
                    vertex2.u = param7;
                    vertex3.u = param6;
                    vertex0.v = 0;
                    vertex1.v = 0;
                    vertex2.v = 1;
                    vertex3.v = 1;
                    break;
                }
                case ST_Other:
                {
                    vertex0.position = param3.add(param5);
                    vertex1.position = param4.add(param5);
                    vertex2.position = param4.subtract(param5);
                    vertex3.position = param3.subtract(param5);
                    vertex0.u = param6;
                    vertex1.u = param7;
                    vertex2.u = param7;
                    vertex3.u = param6;
                    vertex0.v = 0;
                    vertex1.v = 0;
                    vertex2.v = 1;
                    vertex3.v = 1;
                    break;
                }
                default:
                {
                    break;
                }
            }
            var _loc_9:int = 0;
            while (_loc_9 < VertexCount)
            {
                
                _loc_12 = vertexList[_loc_9];
                param1.push(_loc_12.position.x, _loc_12.position.y, _loc_12.position.z);
                param1.push(_loc_12.u, _loc_12.v);
                _loc_9++;
            }
            var _loc_10:* = param1.length / 5 / 4;
            var _loc_11:* = param2.length / 6;
            _loc_9 = _loc_11;
            while (_loc_9 < _loc_10)
            {
                
                _loc_13 = _loc_9 * 4;
                param2.push(_loc_13, (_loc_13 + 1), _loc_13 + 2, _loc_13, _loc_13 + 2, _loc_13 + 3);
                _loc_9++;
            }
            return;
        }// end function

    }
}
